package com.yc.boottxx.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yc.boottxx.entity.User;
import com.yc.boottxx.mapper.UserMapper;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Company 源辰信息
 *
 * @author navy
 * @date 2024/5/29
 * Email haijunzhou@hnit.edu.cn
 */
@Component
@ServerEndpoint("/talk/{id}")
@Slf4j // 日志注解    @Data
/**
 * WebSocket 会为每一个连接的客户端, 创建一个 TalkDo 对象
 */
public class TalkDo {

    /**
     * 群聊(不分组,全部用户参与聊天)
     */
    // 转换线程安全的set集合
    static Set<Session> sessions = Collections.synchronizedSet(new HashSet<>());

    static UserMapper userMapper;

    @Resource
    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    // 连接方法
    @OnOpen
    public void onConnection(
            @PathParam("id") String id,
            Session session){
        User user = userMapper.selectById(id);
        session.getUserProperties().put("myinfo", user);
        session.getUserProperties().put("id",id);
        sessions.add(session);
        Msg m = new Msg(sessions.stream()
                .map(s->s.getUserProperties().get("id").toString())
                .collect(Collectors.toList()),
                sessions.stream()
                        .map(s->(User)s.getUserProperties().get("myinfo"))
                        .collect(Collectors.toList()),
                "text:" + id + "上线了!",
                session.getUserProperties().get("id").toString());
        String json = m.toString();
        sessions.forEach(s->{
            try {
                s.getBasicRemote().sendText(json);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });
        log.info("上线了: " + id);
    }

    // 关闭方法
    @OnClose
    public void onClose( Session session){
        sessions.remove(session);
        Msg m = new Msg(sessions.stream()
                .map(s->s.getUserProperties().get("id").toString())
                .collect(Collectors.toList()),
                sessions.stream()
                        .map(s->(User)s.getUserProperties().get("myinfo"))
                        .collect(Collectors.toList()),
                "text:"+session.getUserProperties().get("id") + "下线了!",
                session.getUserProperties().get("id").toString());
        String json = m.toString();
        sessions.forEach(s->{
            try {
                s.getBasicRemote().sendText(json);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });
        log.info("下线了: " + session.getUserProperties().get("id"));
    }

    // 接收消息方法
    @OnMessage
    public void onMessage( Session session, String msg){
        Msg m = new Msg(sessions.stream()
                                .map(s->s.getUserProperties().get("id").toString())
                                .collect(Collectors.toList()),
                        sessions.stream()
                        .map(s->(User)s.getUserProperties().get("myinfo"))
                        .collect(Collectors.toList()),
                        msg,
                        session.getUserProperties().get("id").toString());
        String json = m.toString();
        sessions.forEach(s->{
            try {
                s.getBasicRemote().sendText(json);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });
        log.info( session.getUserProperties().get("id") + "说:" + json);
    }

}

@Data
@AllArgsConstructor
@NoArgsConstructor
class Msg{

    static ObjectMapper objectMapper = new ObjectMapper();

    // 在线用户
    List<String> onlines;

    List<User> onlinesUser;

    // 消息文本
    String message;

    // 发送者
    String sender;

    @Override
    public String toString() {
        try {
            return objectMapper.writeValueAsString(this);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}
